package com.vtech.ws.cxf.rs.impl;

import com.google.common.net.HttpHeaders;
import com.vtech.ws.cxf.rs.FileService;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/**
 * TODO
 *
 * @author houzhiwei
 * @date 2018/9/4 17:36
 */
@Service
public class FileServiceImpl implements FileService {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileServiceImpl.class);

    @Override
    public Response uploadFile(Attachment targetFile, String username) {
        DataHandler dataHandler = targetFile.getDataHandler();
        try {
            String originalFileName = new String(dataHandler.getName().getBytes("UTF-8"), "UTF-8");
            InputStream ins = dataHandler.getInputStream();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String saveLoc = "H:/GIS data/demo/output" + File.separator + sdf.format(new Date()) + "_" + originalFileName;
            System.out.println(saveLoc);

            FileUtils.copyInputStreamToFile(ins, new File(saveLoc));
            FileUtils.copyToFile(ins, new File(saveLoc));
//            targetFile.transferTo(new File(saveLoc));
//            ins.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            LOGGER.error("UnsupportedEncodingException");
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()).build();
        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.error("IOException");
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()).build();
        } finally {

        }
        return Response.ok(username + ", File uploaded success!").build();
    }

    @Override
    public Response uploadSmallFile(HttpServletRequest request) {

        //检测是不是存在上传文件
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            List<FileItem> items = null;
            try {
                items = upload.parseRequest(request);

                for (FileItem item : items) {
                    // 不是普通表单
                    if (!item.isFormField()) {
                        File dest = new File(changeFilename(item.getName()));
                        item.write(dest);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();

            }
        }

        return Response.ok("File uploaded success!").build();
    }

    @Override
    public Response uploadFiles(List<Attachment> attachments, HttpServletRequest request) {
        for (Attachment attachment : attachments) {
            DataHandler handler = attachment.getDataHandler();
            try {
                InputStream is = handler.getInputStream();
                //test
                String filename = attachment.getContentDisposition().getParameter("filename");
                System.out.println("fileName1 Here" + filename);

                MultivaluedMap<String, String> map = attachment.getHeaders();
                System.out.println("fileName2 Here" + getFileName(map));
                OutputStream out = new FileOutputStream(new File("H:/GIS data/demo/uploads/" + getFileName(map)));

                int read = 0;
                byte[] bytes = new byte[1024];
                while ((read = is.read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                }
                is.close();
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public Response download() {
        try {
            //TODO 真实的文件目录
            //String contextPath = Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath();
            //filename = contextPath + File.separator + filename;
            String filename = "H:/GIS data/demo/output/20180905151100_3.gif";
            return setDownloadResponse(filename);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage()).build();
        }
    }


    private Response setDownloadResponse(String filename) throws UnsupportedEncodingException {
        // 这里的filename不能URLEncoder
        File file = new File(filename);
        filename = URLEncoder.encode(filename, "UTF-8");
        return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                .header(HttpHeaders.CONTENT_LENGTH, file.length()).build();
    }

    @Override
    public Response exportFile(String name, HttpServletResponse response) {
        return null;
    }

    /**
     * get file name from header
     *
     * @param header
     * @return
     */
    private String getFileName(MultivaluedMap<String, String> header) {

        String[] contentDisposition = header.getFirst(HttpHeaders.CONTENT_DISPOSITION).split(";");
        for (String filename : contentDisposition) {
            if ((filename.trim().startsWith("filename"))) {
                String[] name = filename.split("=");
                String exactFileName = name[1].trim().replaceAll("\"", "");
                return exactFileName;
            }
        }
        return "unknown";
    }

    private String changeFilename(String name) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String saveLoc = "H:/GIS data/demo/output" + File.separator + sdf.format(new Date()) + "_" + name;
        System.out.println(saveLoc);
        return saveLoc;
    }
}
